import type { PtData } from "./src/PtData";
import type { PtContainer, PtPage } from "./src/register";

export type Emptyable<T, E = undefined> = T | E;

// 数字、百分比
export type Numberic = number | `${number}`;
export type Percent = `${number}%`;
export type Sizeic = Numberic | Percent;

// hex颜色、rgb颜色
export type HexColor = `#${string}`;
export type RGBColor = `rgb(${number}, ${number}, ${number})`;
export type RGBAColor = `rgba(${number}, ${number}, ${number}, ${number})`;
export type Color = HexColor | RGBColor | RGBAColor;
export type ImageFit = 'fill' | 'contain' | 'cover' | 'none';

export type Align = 'left' | 'center' | 'right';
export type Vertical = 'top' | 'middle' | 'bottom';
export type TextAlign = 'left' | 'center' | 'right' | 'justify';
export type FontWeight = 100 | 400 | 700;

export interface CInstance {
    el: JSX.Element;
}

export interface Source {
    type: 'image' | 'video' | 'file' | 'audio';
    src: string; // 预览前展示地址
    raw: string; // 预览地址
    preview?: boolean; // 是否展示预览
}

export type DataType = Record<string, any>;

export type PtComponentConst = PtComponentBase & {
    type: string;
    value: DataType;
    render: DataType;
}

export interface PtComponent<type extends string, T extends DataType, K extends DataType> extends PtComponentConst {
    type: type;
    value: T;
    render: Partial<K>;
}

export interface PtComponentBase {
    // 组件名称
    name: string;

    // 组件在页面中的信息
    options: Options;
}

export type Options = PtOptionsBase & Partial<PtOptionsPosition>;

interface PtOptionsBase {
    width: Numberic | Percent;
    height: Numberic | Percent;
}
interface PtOptionsPosition {
    // 如果包含positionAlign属性，x可以不传
    x: Numberic | Percent;
    y: Numberic | Percent;
    // 自身定位位置
    originAlign: Align | null;
    originVertical: Vertical | null;
    // 基于上一层的坐标，如果设置，origin参数将忽略
    positionAlign: Align | null;
    positionVertical: Vertical | null;
}

export interface Page {
    // 参照模式
    // normal 单一页（默认模式）
    // loop 多页（数据不同页面类似）。根据数据集列表的数量决定
    mode?: 'normal' | 'loop';

    // 相对数据集，默认为 'base'，表示如果不指定明确位置，寻找的数据将默认从base中获取
    // loop 模式必须指定数据集，而且是一个数据集列表，表示每一层循环中将要使用的数据（一般为数据列表中的每一项作为origin），例：base.list.*
    // normal 模式需要指定唯一的数据集。如果数据集是个列表，将只使用列表中的第一项渲染页面
    // 数据集可以多指定，将分散的数据集合到一个列表使用（需要保证每个数据的字段都是相同的）
    origin?: string | string[];

    // 页面标题
    title: string;

    // 页面描述信息
    description?: string;

    // 展示条件
    condition?: string;

    // 页面组件配置
    components: PtComponentConst[];
}

// 主结构
export interface PtPageJson {
    // 版本号
    version: number;

    // 最后编辑时间
    lastEditTime: string;

    // 页面ID
    id?: number;

    // 页面标题
    title: string;

    // 项目配置
    performance: ProjectPerformance;

    // 公共数据，全局可用
    data: {
        [key: string]: any;
        base: DataType;
    };

    // 页面组件
    pages: Page[];
}

export interface ProjectPerformance {
    // A4纸长宽
    width: Numberic;
    height: Numberic;
}

export interface ComponentRenderx {
    el: JSX.Element;
    onRerender?: () => void;
}

export type DataNamespace = string | DataType;

export type ComponentRegister = {
    name: string;
    render: (instance: PtContainer, comp: PtComponentConst, parentComp?: PtComponentConst, data?: PtData) => JSX.Element;
    getPreloadSource?: (instance: PtPage, comp: PtComponentConst, data?: PtData) => Source[];
};

export type {
    PtContainer,
    PtPage
}